#include "FileParser.h"

std::set<std::string> FileParser::stopWords;

void FileParser::initTypes() {
    FileType * document = new DocumentType();
    FileType * photo = new PhotoType();
    fileTypes["audio/mpeg"] = new AudioType();
    fileTypes["text/code"] = new CodeType();
    // Ojo aqui cuando destruyo
    fileTypes["application/pdf"] = document;
    fileTypes["document/txt"] = document;
    fileTypes["image/png"] = photo;
    fileTypes["image/jpeg"] = photo;
    regcomp(&regexSource, "^.*\\.h$|^.*\\.hpp$|^.*\\.cpp$|^.*\\.c$|^.*\\.php$|^.*\\.py$", REG_EXTENDED | REG_ICASE);
    regcomp(&regexText, "^.*\\.txt$", REG_EXTENDED | REG_ICASE);
}

void FileParser::initStopWords() {
    std::string path("./stopwords.txt");
    std::ifstream configFile;
    configFile.exceptions(std::ifstream::badbit);
    configFile.open(path.c_str(), std::ios::in);
    std::string values;
    getline(configFile, values);
    while (!configFile.eof()) {
        if (!values.empty()) {
            stopWords.insert(values);
            values.clear();
        }
        getline(configFile, values);
    }
    configFile.close();
}

void FileParser::initLibExtractor() {
    plugins = EXTRACTOR_loadDefaultLibraries();
    plugins = EXTRACTOR_loadConfigLibraries(plugins, "libextractor_pdf:libextractor_mp3:libextractor_ogg:libextractor_png:libextractor_jpeg:libextractor_mpeg");
}

void FileParser::parse(std::string path) {
    EXTRACTOR_KeywordList * md_list = NULL;
    std::string mime("empty");
    const char * temp=NULL;
    std::string fileExtension = StaticUtils::extractFileName(path);
    int statusTxt, statusCode;
    Catalogues* catalog = NULL;
    std::map<std::string, FileType*>::iterator ite;
    md_list = EXTRACTOR_getKeywords(plugins, path.c_str());
    try {
        if (md_list != NULL && EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE, md_list)!=NULL) {
            mime = EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE, md_list);
        } else {
            // Proceso por extension
            statusCode = regexec(&regexSource, fileExtension.c_str(), (size_t) 0, NULL, 0);
            statusTxt = regexec(&regexText, fileExtension.c_str(), (size_t) 0, NULL, 0);
            if (statusCode == 0) {
                mime = "text/code";
            }
            if (statusTxt == 0) {
                mime = "document/txt";
            }
        }
        ite = fileTypes.find(mime);
        catalog = engine->getCatalogue(mime);
        if (ite != fileTypes.end()) {
            (ite->second)->parse(path, catalog, md_list);
        }
    } catch (int& a) {
        // Loguear
    } catch (...) {
        // Loguear
    }
    EXTRACTOR_freeKeywords(md_list);
}

void FileParser::removeDocuments(std::string path) {
    EXTRACTOR_KeywordList * md_list = NULL;
    int statusTxt, statusCode;
    Catalogues* catalog = NULL;
    std::string mime("empty");
    std::string fileExtension = StaticUtils::extractFileName(path);
    md_list = EXTRACTOR_getKeywords(plugins, path.c_str());
    try {
        if (md_list != NULL) {
            mime = EXTRACTOR_extractLast(EXTRACTOR_MIMETYPE, md_list);
        } else {
            // Proceso por extension
            statusCode = regexec(&regexSource, fileExtension.c_str(), (size_t) 0, NULL, 0);
            statusTxt = regexec(&regexText, fileExtension.c_str(), (size_t) 0, NULL, 0);
            if (statusCode == 0) {
                mime = "text/code";
            }
            if (statusTxt == 0) {
                mime = "document/txt";
            }
        }
        catalog = engine->getCatalogue(mime);
        catalog->eliminarDocumento(path);
    } catch (int& a) {
        // Loguear
    } catch (...) {
        // Loguear
    }
    EXTRACTOR_freeKeywords(md_list);
}


FileParser::~FileParser() {
    fileTypes["application/pdf"] = NULL;
    fileTypes["image/png"] = NULL;
    engine = NULL;
    std::map<std::string, FileType*>::iterator ite = fileTypes.begin();
    for (; ite != fileTypes.end(); ite++) {
        if (ite->second != NULL) {
            delete(ite->second);
        }
    }
    fileTypes.clear();
    EXTRACTOR_removeAll(plugins);
    plugins = NULL;
    stopWords.clear();
    regfree(&regexSource);
    regfree(&regexText);
}